﻿using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using System.Text;
using VaccinationHost.Model;

namespace VaccinationHost.Extend
{
    /// <summary>
    /// 注册JWT验权扩展类
    /// </summary>
    public static class JwtAuthenticationServiceCollectionExtensions
    {
        /// <summary>
        /// 注册JWT验权扩展
        /// </summary>
        /// <param name="services"></param>
        /// <param name="Configuration"></param>
        /// <returns></returns>
        public static IServiceCollection AddJwtAuthentication(this IServiceCollection services)
        {
            // 这里使用对称加密
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)//Scheme
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    //JWT有一些默认的属性，就是给鉴权时就可以筛选了
                    ValidateIssuer = true,//是否验证Issuer
                    ValidateAudience = true,//是否验证Audience
                    ValidateLifetime = true,//是否验证失效时间
                    //ValidateLifetime = false,//是否验证失效时间
                    ValidateIssuerSigningKey = true,//是否验证SecurityKey
                    //ValidateIssuerSigningKey = false,//是否验证SecurityKey
                    ValidAudience = "ssss",//
                    ValidIssuer = "ssss",//Issuer，这两项和前面签发jwt的设置一致
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("MIGfMA0GDE49f4qGSIb3DQEBAQUAA4NADCBiQKBgQDI2a2EJ7m872v0fyoSDJT2o1+SitIeJSWtLJU8/Wz2m7gStexaseDR2keD+Lka6DSTy8gt9UwfgVQo6uKjVLG5Ex7PiGOODVqAEghBuS7JzIYU5RvI54nNDAPfnJsas96mSA7L/D7RTE2drj6hfoZjJpMPZUQI/B1Qjb5H3K3NwIDAQAB"))
                };

                //如果验证不通过，可以给一个时间注册一个动作，这动作就是指定返回的结果；
                options.Events = new JwtBearerEvents
                {
                    //此处为权限验证失败后触发的事件
                    OnChallenge = context =>
                    {
                        //此处代码为终止.Net Core默认的返回类型和数据结果，这个很重要哦，必须
                        context.HandleResponse();
                        //自定义自己想要返回的数据结果，我这里要返回的是Json对象，通过引用Newtonsoft.Json库进行转换 
                        //自定义返回的数据类型
                        context.Response.ContentType = "application/json";
                        //自定义返回状态码，默认为401 我这里改成 200
                        context.Response.StatusCode = StatusCodes.Status401Unauthorized;

                        context.Response.WriteAsync(JsonConvert.SerializeObject(new OpResult() { Code = 401, Message = "未登录授权。" }));
                        return Task.FromResult(0);
                    }
                };
            });
            return services;
        }
    }
}
